package day_02_ThreadCommunicate;

/**
 * 资源类--阳哥的方式
 */
class MyResourceNew{

    private int number = 0;

    public synchronized void increment() {
        // 1、判断
        if(number != 0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 2、干活
        number++;
        System.out.println(Thread.currentThread().getName() + "\t" + number);
        // 3、通知
        this.notifyAll();
    }

    public synchronized void decrement() {
        // 1、判断
        if(number == 0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 2、干活
        number--;
        System.out.println(Thread.currentThread().getName() + "\t" + number);
        // 3、通知
        this.notifyAll();
    }

}

/**
 * @Description 线程间通信--两个线程交替操作资源类【方式二：阳哥的方式，实现线程的交互操作（但是还存在线程的虚假唤醒问题）】
 * @Author shihan
 * @Date 2020/10/25 17:13
 * @Version 1.0
 */
public class ThreadWaitNotifyDemoNew {

    /**
     * 实现两个线程交替操作：
     * 线程A将数 +1，线程B将数 -1，交替执行10轮
     *【判断/干活/通知】
     * 1、判断当前情况，是不是由你来执行，不是则直接 wait；
     * 2、当前情况是由自己来执行，则干活；
     * 3、干完活之后，通知唤醒其他等待的线程；
     * PS：阳哥的这三段论很好，值得细品，我自己那种方式，省去了必须在最后多加上一个 notifyAll
     * @param args
     */
    public static void main(String[] args) {
        MyResourceNew myResourceNew = new MyResourceNew();

        new Thread(() -> { for (int i = 0; i < 10; i++)  myResourceNew.increment(); },"线程A").start();
        new Thread(() -> { for (int i = 0; i < 10; i++)  myResourceNew.decrement(); },"线程B").start();

    }
}
